using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Roslyn.Compilers.CSharp;

namespace ContentOverContainer
{
    public class AnyAttribute : MultiplicityAttribute
    {
        public AnyAttribute(Type pContainerType) : base(MultiplicityKind.Any,pContainerType){}

        public static new bool EqualsName(string pAttributeName)
        {
            //string name = typeof(MultiplicityAttribute).Name;
            return pAttributeName.Equals("AnyAttribute") || pAttributeName.Equals("Any");
        }
    }

    public class OptionAttribute : MultiplicityAttribute
    {
        public OptionAttribute() : base(MultiplicityKind.Option, null){}

        public static new bool EqualsName(string pAttributeName)
        {
            //string name = typeof(MultiplicityAttribute).Name;
            return pAttributeName.Equals("OptionAttribute") || pAttributeName.Equals("Option");
        }
    }

    public class MultiplicityAttribute : Attribute
    {
        private MultiplicityKind m_MulType = MultiplicityKind.Option;
        private Type m_ContainerType = null; //only used for  MultiplicityType.Any

        public Type ContainerType
        {
            get
            {
                return m_ContainerType;
            }
        }

        //public MultiplicityAttribute(MultiplicityKind pMulType) :this (pMulType, typeof(List<>)){}

        public MultiplicityAttribute(MultiplicityKind pMulType, Type pContainerType)
        {
            m_MulType = pMulType;
            if (m_MulType == MultiplicityKind.Any)
            {
                if (pContainerType != null)
                {
                    if (!pContainerType.IsGenericType || pContainerType.IsAssignableFrom(typeof (IList)))
                        //alternatively: .GetInterfaces().Contains(typeof(IList))
                        throw new ArgumentException("Type must be a generic container type implementing IList.",
                                                    "pContainerType");
                    m_ContainerType = pContainerType;
                }
            }
        }

        public static bool EqualsName(string pAttributeName)
        {
            //string name = typeof(MultiplicityAttribute).Name;
            return pAttributeName.Equals("MultiplicityAttribute") || pAttributeName.Equals("Multiplicity");
        }
    }

    public class MultiplicityInfo
    {
        public MultiplicityKind Kind { get; set; }
        public TypeSyntax Type { get; set; }
    }

    public enum MultiplicityKind
    {
        None,
        Option,
        Any
    }
}
